package org.mindrive.system.service.system;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.mindrive.system.collection.system.*;
import org.mindrive.system.core.MindriveException;
import org.mindrive.system.parameter.BaseSearchParameter;
import org.mindrive.system.parameter.system.RoleParameter;
import org.mindrive.system.parameter.system.RolePeopleParameter;
import org.mindrive.system.service.BaseService;
import org.mindrive.system.util.UUIDGenerator;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RoleService extends BaseService {

    private List<String> getPermissions(String roleCode) {

        QueryWrapper<PermissionEntity> query = new QueryWrapper<PermissionEntity>();

        if (!roleCode.equals("")) {
            query.like("role_code", roleCode);
        }
        List<PermissionEntity> permissions2 = permissionDao.list(query);
        List<String> list = new ArrayList<String>();
        for (PermissionEntity permission : permissions2) {
            list.add(permission.getId());
        }
        return list;

    }

    public RoleEntity create(RoleParameter input) {
        UserEntity loginUser = getLoginUser();
        QueryWrapper<RoleEntity> query = new QueryWrapper<RoleEntity>();
        query.eq("name", input.getName());

        int count = roleDao.count(query);
        if (count != 0) {
            throw new MindriveException("角色名称已存在");
        }
        RoleEntity role = new RoleEntity();
        role.setCode(UUIDGenerator.generateOTP(8));
        if (input.getWorkspaceId() != null && !"".equals(input.getWorkspaceId())) {
            role.setWorkspaceId(input.getWorkspaceId());
        } else {
            role.setWorkspaceId("");
        }
        role.setName(input.getName());
        role.setCreatedAt(new Date());
        role.setCreator(loginUser.getUserId());
        roleDao.save(role);
        return role;
    }

    public void update(String id, RoleParameter input) {
        RoleEntity role = roleDao.getById(id);
        String code = role.getCode();
        if (ROLE_CODE_SYSTEM_ADMIN.equals(code)) {
            throw new MindriveException("系统管理员为默认角色，不能修改");
        }
        if (ROLE_CODE_SYSTEM_USER.equals(code)) {
            throw new MindriveException("普通用户为默认角色，不能修改");
        }
        if (ROLE_CODE_DATABASE_ADMIN.equals(code)) {
            throw new MindriveException("数据库管理员为默认角色，不能修改");
        }
        if (ROLE_CODE_WORKSPACE_ADMIN.equals(code)) {
            throw new MindriveException("工作区管理员为默认角色，不能修改");
        }
        if (ROLE_CODE_WORKSPACE_USER.equals(code)) {
            throw new MindriveException("工作区用户为默认角色，不能修改");
        }

        QueryWrapper<RoleEntity> query = new QueryWrapper<RoleEntity>();
        query.ne(ID, id).eq("name", input.getName());
        if (input.getWorkspaceId() != null && !"".equals(input.getWorkspaceId())) {
            query.eq("workspace_id", input.getWorkspaceId());
        } else {
            query.eq("workspace_id", "");
        }

        int count = roleDao.count(query);
        if (count != 0) {
            throw new MindriveException("角色名称已经存在。");
        }
        RoleEntity update = new RoleEntity();
        update.setId(id);
        update.setName(input.getName());
        roleDao.updateById(update);

    }

    public RoleEntity detail(String id) {
        RoleEntity role = roleDao.getById(id);

        QueryWrapper<RolePermissionEntity> queryPermission = new QueryWrapper<RolePermissionEntity>();
        queryPermission.eq("role_id", role.getId());
        List<RolePermissionEntity> rolePermissions = rolePermissionDao.list(queryPermission);
        List<String> permissions = rolePermissions.stream().map(item -> item.getPermissionId())
                .collect(Collectors.toList());
        role.setPermissions(permissions);
        return role;

    }

    public void delete(String id) {
        RoleEntity role = roleDao.getById(id);
        String code = role.getCode();
        if (ROLE_CODE_SYSTEM_ADMIN.equals(code)) {
            throw new MindriveException("系统管理员为默认角色，不能删除");
        }

        if (ROLE_CODE_SYSTEM_USER.equals(code)) {
            throw new MindriveException("普通用户为默认角色，不能删除");
        }
        if (ROLE_CODE_DATABASE_ADMIN.equals(code)) {
            throw new MindriveException("数据库管理员为默认角色，不能删除");
        }

        if (ROLE_CODE_WORKSPACE_ADMIN.equals(code)) {
            throw new MindriveException("工作区管理员为默认角色，不能删除");
        }
        if (ROLE_CODE_WORKSPACE_USER.equals(code)) {
            throw new MindriveException("工作区用户为默认角色，不能删除");
        }

        QueryWrapper<UserRoleEntity> query2 = new QueryWrapper<UserRoleEntity>();
        query2.eq("role_id", id);
        userRoleDao.remove(query2);

        roleDao.removeById(id);

        QueryWrapper<RolePermissionEntity> query3 = new QueryWrapper<RolePermissionEntity>();
        query3.eq("role_id", id);
        rolePermissionDao.remove(query3);

    }

    public List<String> getRolesForUser(String id) {

        List<String> roleList = userDao.getRoleIds(id);

        return roleList;
    }

    public boolean userIsInRole(String id, String roleId) {

        List<String> roleList = userDao.getRoleIds(id);

        if (roleList != null && !roleList.isEmpty()) {
            return roleList.contains(roleId);
        } else {
            return false;
        }
    }

    public boolean userHaveRoleCode(String id, String roleCode) {
        QueryWrapper<RoleEntity> roleQuery = new QueryWrapper<RoleEntity>();
        roleQuery.eq("code", roleCode);
        RoleEntity role = roleDao.getOne(roleQuery, false);
        List<String> roleList = userDao.getRoleIds(id);
        if (roleList != null && !roleList.isEmpty()) {
            return roleList.contains(role.getId());
        } else {
            return false;
        }
    }

    public void setUserRoles(String userId, List<String> roles, String workspaceId) {
        QueryWrapper<UserRoleEntity> query = new QueryWrapper<UserRoleEntity>();
        query.eq("user_id", userId);
        userRoleDao.remove(query);
        for (String roleId : roles) {
            UserRoleEntity item = new UserRoleEntity();
            item.setRoleId(roleId);
            item.setUserId(userId);
            item.setWorkspaceId(workspaceId);
            userRoleDao.save(item);
        }
    }

    public void setPermissions(String id, List<String> permissions) {

        RoleEntity role = roleDao.getById(id);
        String code = role.getCode();
        if (ROLE_CODE_SYSTEM_ADMIN.equals(code)) {
            throw new MindriveException("系统管理员为默认角色，不能设置");
        }

        if (ROLE_CODE_SYSTEM_USER.equals(code)) {
            throw new MindriveException("普通用户为默认角色，不能设置");
        }
        if (ROLE_CODE_DATABASE_ADMIN.equals(code)) {
            throw new MindriveException("数据库管理员为默认角色，不能设置");
        }

        if (ROLE_CODE_WORKSPACE_ADMIN.equals(code)) {
            throw new MindriveException("工作区管理员为默认角色，不能设置");
        }
        if (ROLE_CODE_WORKSPACE_USER.equals(code)) {
            throw new MindriveException("工作区用户为默认角色，不能设置");
        }

        QueryWrapper<RolePermissionEntity> query = new QueryWrapper<RolePermissionEntity>();
        query.eq("role_id", id);
        rolePermissionDao.remove(query);

        for (String permissionId : permissions) {
            RolePermissionEntity item = new RolePermissionEntity();
            item.setRoleId(id);
            item.setPermissionId(permissionId);
            item.setCreatedAt(new Date());
            rolePermissionDao.save(item);
        }
    }

    public Map<String, Object> searchRoles(BaseSearchParameter parameter) {

        UserEntity loginUser = getLoginUser();
//        String workspaceId = loginUser.getCurrentWorkspaceId();

        QueryWrapper<RoleEntity> roleQuery = new QueryWrapper<RoleEntity>();

        Map<String, Object> result = new HashMap<String, Object>();

        if (parameter.getName() != null && !parameter.getName().equals("")) {
            roleQuery.like("name", parameter.getName());
        }
        roleQuery.notIn("code",
                Arrays.asList(ROLE_CODE_SYSTEM_ADMIN, ROLE_CODE_SECURITY_SECRET, ROLE_CODE_SECURITY_AUDIT));
//        roleQuery.eq("workspace_id", workspaceId);

        long count = roleDao.count(roleQuery);

        roleQuery.orderByAsc("CREATED_AT");
        List<RoleEntity> roles = null;
        Page<RoleEntity> page = page(RoleEntity.class, parameter.getPageSize(), parameter.getCurrentPage());
        if (page == null) {
            roles = roleDao.list(roleQuery);
        } else {
            roleDao.page(page, roleQuery);
            roles = page.getRecords();
        }

        for (RoleEntity role : roles) {
            QueryWrapper<RolePermissionEntity> queryPermission = new QueryWrapper<RolePermissionEntity>();
            queryPermission.eq("role_id", role.getId());
            List<RolePermissionEntity> rolePermissions = rolePermissionDao.list(queryPermission);
            List<String> permissions = rolePermissions.stream().map(item -> item.getPermissionId())
                    .collect(Collectors.toList());
            role.setPermissions(permissions);
            QueryWrapper<UserRoleEntity> userRoleQuery = new QueryWrapper<>();
            userRoleQuery.eq("ROLE_ID" , role.getId());
            final int count1 = userRoleDao.count(userRoleQuery);
            role.setUserNum(count1);
        }

        result.put(COUNT, count);
        result.put(LIST, roles);

        return result;

    }

    public List<String> getUsersByRoleId(String roleId) {
        RoleEntity role = roleDao.getById(roleId);
        QueryWrapper<UserRoleEntity> query = new QueryWrapper<UserRoleEntity>();
        query.eq("role_id", role.getId());

        List<UserRoleEntity> list = userRoleDao.list(query);
        if (list.size() == 0) {
            throw new MindriveException("【" + role.getName() + "】中没有成员");
        }
        List<String> assigneeList = list.stream().map(item -> item.getUserId()).collect(Collectors.toList());
        return assigneeList;
    }

    public Map<String, Object> getUsersForRole(String roleId, BaseSearchParameter parameter) {
        RoleEntity role = roleDao.getById(roleId);
        if (role == null) {
            throw new MindriveException("没有找到实例");
        }

        QueryWrapper<UserEntity> query = new QueryWrapper<UserEntity>();

        QueryWrapper<UserRoleEntity> queryUserRole = new QueryWrapper<UserRoleEntity>();
        queryUserRole.eq("role_id", roleId);
        queryUserRole.select("user_id");

        List<UserRoleEntity> roleList = userRoleDao.list(queryUserRole);
        List<String> userIds = roleList.stream().map(item -> item.getUserId()).collect(Collectors.toList());
        if (userIds.size() == 0) {
            Map<String, Object> result = new HashMap<String, Object>();
            result.put(COUNT, 0);
            result.put(LIST, null);
            return result;
        } else {
            query.in("id", userIds);
        }

        if (parameter.getName() != null && !parameter.getName().equals("")) {
            query.and(
                    wrapper -> wrapper.like("user_name", parameter.getName()).or().like("user_id", parameter.getName())
                            .or().like("email", parameter.getName()).or().like("phone_number", parameter.getName()));
        }

        long count = userDao.count(query);

        Page<UserEntity> page = page(UserEntity.class, parameter.getPageSize(), parameter.getCurrentPage());
        List<UserEntity> users = null;
        if (page == null) {
            users = userDao.list(query);
        } else {
            userDao.page(page, query);
            users = page.getRecords();
        }

        for (UserEntity user : users){
            if (role.getPersonInCharge() != null && !role.getPersonInCharge().equals("")){
                if (role.getPersonInCharge().equals(user.getId())){
                    user.setPersonInCharge(YES_STATUS);
                }else {
                    user.setPersonInCharge(NO_STATUS);
                }
            }else {
                user.setPersonInCharge(NO_STATUS);
            }
        }
        Map<String, Object> result = new HashMap<String, Object>();
        result.put(COUNT, count);
        result.put(LIST, users);
        return result;
    }

    public void officerInCharge(RolePeopleParameter parameter){
        RoleEntity role = roleDao.getById(parameter.getRole_id());
        role.setPersonInCharge(parameter.getUser_id());
        roleDao.updateById(role);
    }

    /**
     * 取得没有该角色的用户
     *
     * @param roleId
     * @param parameter
     * @return
     */
    public Map<String, Object> getUsersForNoRole(String roleId, BaseSearchParameter parameter) {
        RoleEntity role = roleDao.getById(roleId);
        if (role == null) {
            throw new MindriveException("没有找到实例");
        }

        QueryWrapper<UserEntity> query = new QueryWrapper<UserEntity>();
        query.notIn("user_id", Arrays.asList("admin"));

        QueryWrapper<UserRoleEntity> queryUserRole = new QueryWrapper<UserRoleEntity>();
        queryUserRole.eq("role_id", roleId);
        queryUserRole.select("user_id");
        List<UserRoleEntity> roleList = userRoleDao.list(queryUserRole);

        List<String> userIds = roleList.stream().map(item -> item.getUserId()).collect(Collectors.toList());
        if (userIds.size() != 0) {
            query.notIn("id", userIds);
        }

        if (parameter.getName() != null && !parameter.getName().equals("")) {
            query.and(
                    wrapper -> wrapper.like("user_name", parameter.getName()).or().like("user_id", parameter.getName())
                            .or().like("email", parameter.getName()).or().like("phone_number", parameter.getName()));
        }


        long count = userDao.count(query);

        Page<UserEntity> page = page(UserEntity.class, parameter.getPageSize(), parameter.getCurrentPage());
        List<UserEntity> employees = null;
        if (page == null) {
            employees = userDao.list(query);
        } else {
            userDao.page(page, query);
            employees = page.getRecords();
        }

        Map<String, Object> result = new HashMap<String, Object>();
        result.put(COUNT, count);
        result.put(LIST, employees);
        return result;
    }

    public void addUsersForRole(String roleId, List<String> userIds) {

        RoleEntity role = roleDao.getById(roleId);
        if (role == null) {
            throw new MindriveException("没有找到实例");
        }

        for (String userId : userIds) {
            QueryWrapper<UserRoleEntity> userQueryRelation = new QueryWrapper<UserRoleEntity>();
            userQueryRelation.eq("user_id", userId);
            int count1 = userRoleDao.count(userQueryRelation);
            if (count1 > 0){
                throw new MindriveException("当前用户已绑定科室");
            }
            QueryWrapper<UserRoleEntity> queryRelation = new QueryWrapper<UserRoleEntity>();
            queryRelation.eq("role_id", role.getId()).eq("user_id", userId);
            int count = userRoleDao.count(queryRelation);
            if (count == 0) {
                UserRoleEntity item1 = new UserRoleEntity();
                item1.setUserId(userId);
                item1.setWorkspaceId(role.getWorkspaceId());
                item1.setRoleId(role.getId());
                userRoleDao.save(item1);
            }
        }

    }

    public void deleteUsersForRole(String roleId, List<String> userIds) {
        RoleEntity role = roleDao.getById(roleId);
        if (role == null) {
            throw new MindriveException("没有找到实例");
        }

        for (String userId : userIds) {
            QueryWrapper<UserRoleEntity> item1 = new QueryWrapper<UserRoleEntity>();
            item1.eq("user_id", userId);
            item1.eq("role_id", role.getId());
            userRoleDao.remove(item1);
        }

    }


}
